﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace Awsc.DataAcquisitionSys.Core.Model.Config
{
    public class CollectorConfig
    {
        /// <summary>
        /// 采集器名称
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 采集器型号
        /// </summary>
        public string Model { get; set; }
        /// <summary>
        /// 如果使用串口通信，则为串口号
        /// </summary>
        public string COMPort { get; set; }
        /// <summary>
        /// SlaveId
        /// </summary>
        public byte SlaveAddress { get; set; }
        /// <summary>
        /// 采集器IP地址，如果使用TCP通信，则为IP地址
        /// </summary>
        public string IP { get; set; }
        /// <summary>
        /// 采集器端口，如果使用TCP通信，则为端口号
        /// </summary>
        public int Port { get; set; }
        /// <summary>
        /// 输入模拟量量个数
        /// </summary>
        public ushort AICount { get; set; }
        /// <summary>
        /// 输出模拟量个数
        /// </summary>
        public ushort AOCount { get; set; }
        /// <summary>
        /// 输入数字量个数
        /// </summary>
        public ushort DICount { get; set; }
        /// <summary>
        /// 输出数字量个数
        /// </summary>
        public ushort DOCount { get; set; }
        /// <summary>
        /// 采集频率，单位为这毫秒
        /// </summary>
        public int UpdateFreq { get; set; }
        public List<RegisterConfig> InputRegisters { get; set; } = new List<RegisterConfig>();
        public List<RegisterConfig> OutputRegisters { get; set; } = new List<RegisterConfig>();

        public List<CoilConfig> InputCoils { get; set; } = new List<CoilConfig>();
        public List<CoilConfig> OutputCoils { get; set; } = new List<CoilConfig>();

        [Newtonsoft.Json.JsonIgnore]
        [System.Text.Json.Serialization.JsonIgnore]
        public List<SensorConfig> AllSensorConfigs
        {
            get
            {
                List<SensorConfig> result = [.. InputCoils, .. OutputCoils, .. InputRegisters, .. OutputRegisters];
                return result;
            }
        }

    }

    public abstract class SensorConfig
    {
        public string SensorType { get; set; }
        /// <summary>
        /// 传感器名称
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 采集器名称
        /// </summary>
        public string CollectorName { get; set; }
        /// <summary>
        /// 采集器通道ID
        /// </summary>
        public int CollectorChannelId { get; set; }
        public virtual bool IsCoil { get; }


    }

    public class RegisterConfig : SensorConfig
    {

        public RegisterType RegisterType { get; set; } = RegisterType.AI;
        /// <summary>
        /// 
        /// </summary>
        public double OutputMin { get; set; }
        public double OutputMax { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string OutputUnit { get; set; }
        public double RangeMax { get; set; }
        public double RangeMin { get; set; }
        public string RangeUnit { get; set; }
        /// <summary>
        /// 报警最小值，小于 WarnMin 时报警
        /// </summary>
        public double WarnMin { get; set; }
        /// <summary>
        /// 最大报警值，大于 WarnMax 时报警
        /// </summary>
        public double WarnMax { get; set; }
        public int Zero { get; set; }
        /// <summary>
        /// 数值纠正系数，最终输出值= 采集值*KValue
        /// </summary>
        public double KValue { get; set; }
        /// <summary>
        /// 使用AI量创建Coil,如果为true，则会创建一个Coil并以AI量的名称+Coil作为名称
        /// </summary>
        public bool CreatAICoil { get; set; }
        /// <summary>
        /// AI量的值到达OpenValue时，AICoil打开
        /// </summary>
        public double OpenValue { get; set; }
        /// <summary>
        /// AI量的值到达CloseValue时，AICoil关闭
        /// </summary>
        public double CloseValue { get; set; }

        /// <summary>
        /// 其他配置，现用于虚拟采集器中的传感器
        /// </summary>
        public Dictionary<string, object> AdditionalConfig { get; set; } = new Dictionary<string, object>();

        public T GetAdditionConfigValue<T>(string configEntryName)
        {
            if (!AdditionalConfig.ContainsKey(configEntryName))
            {
                throw new KeyNotFoundException(configEntryName);
            }
            return (T)AdditionalConfig[configEntryName];
        }

        public T GetAdditionConfig<T>() where T : class
        {
            if (!AdditionalConfig.Any())
            {
                return null;
            }
            return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(AdditionalConfig));
        }

    }

    public enum RegisterType
    {
        None = -1,
        /// <summary>
        /// 输入模拟量
        /// </summary>
        AI = 0,
        /// <summary>
        /// 输出模拟量
        /// </summary>
        AO = 1
    }


    public class CoilConfig : SensorConfig
    {
        /// <summary>
        /// 线圈类型
        /// </summary>
        public CoilType CoilType { get; set; }
        /// <summary>
        /// 是否反转取值
        /// </summary>
        public bool BeReverse { get; set; }
        public override bool IsCoil { get; } = true;
    }

    public enum CoilType
    {
        None = -1,
        /// <summary>
        /// 输入线圈
        /// </summary>
        DI = 0,
        /// <summary>
        /// 输出线圈
        /// </summary>
        DO = 1,
    }

}